﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace Windows.Toolbar.Controls.Specialized
{
    [TemplateVisualState(GroupName = "CommonStates", Name = NormalState)]
    [TemplateVisualState(GroupName = "CommonStates", Name = FocusedState)]
    [TemplateVisualState(GroupName = "SelectionStates", Name = SelectedState)]
    [TemplateVisualState(GroupName = "SelectionStates", Name = UnselectedState)]
    [TemplateVisualState(GroupName = "MouseStates", Name = MouseOutState)]
    [TemplateVisualState(GroupName = "MouseStates", Name = MouseOverState)]
    public partial class ColorPickerItem : UserControl
    {
        #region Constants

        public const string NormalState = "Normal";
        public const string FocusedState = "Focused";
        public const string SelectedState = "Selected";
        public const string UnselectedState = "Unselected";
        public const string MouseOutState = "MouseOut";
        public const string MouseOverState = "MouseOver";

        #endregion

        #region Fields

        private bool _isMouseOver;

        #endregion

        #region Events

        /// <summary>
        /// Occurs when the user selects this control.
        /// </summary>
        public event EventHandler SelectionChanged;
        /// <summary>
        /// Raises the <see cref="E:Click"/> event.
        /// </summary>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected virtual void OnSelectionChanged(EventArgs e)
        {
            EventHandler eventHandler = SelectionChanged;

            if (eventHandler != null)
            {
                eventHandler(this, e);
            }
        }

        #endregion

        #region Dependency Properties

        /// <summary>
        /// Defines the <see cref="Color"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty ColorProperty =
            DependencyProperty.Register("Color", typeof(Color), typeof(ColorPickerItem), new PropertyMetadata(Colors.Transparent, new PropertyChangedCallback(OnColorChanged)));
        /// <summary>
        /// Gets or sets the color to display.
        /// </summary>
        /// <value>The color to display.</value>
        public Color Color
        {
            get { return (Color)GetValue(ColorProperty); }
            set { SetValue(ColorProperty, value); }
        }

        private static void OnColorChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var owner = o as ColorPickerItem;
            if (owner != null)
            {
                owner.OnColorChanged(e);
            }
        }

        private void OnColorChanged(DependencyPropertyChangedEventArgs e)
        {
            Color newValue = (Color)e.NewValue;

            if (RootElement != null)
            {
                RootElement.Background = new SolidColorBrush(newValue);
            }
        }

        /// <summary>
        /// Defines the <see cref="IsSelected"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty IsSelectedProperty =
            DependencyProperty.Register("IsSelected", typeof(bool), typeof(ColorPickerItem), new PropertyMetadata(false, new PropertyChangedCallback(OnIsSelectedChanged)));
        /// <summary>
        /// Gets or sets a value indicating whether this item is selected.
        /// </summary>
        /// <value>A value indicating whether this item is selected..</value>
        public bool IsSelected
        {
            get { return (bool)GetValue(IsSelectedProperty); }
            set { SetValue(IsSelectedProperty, value); }
        }

        private static void OnIsSelectedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var owner = o as ColorPickerItem;
            if (owner != null)
            {
                owner.OnIsSelectedChanged(e);
            }
        }

        private void OnIsSelectedChanged(DependencyPropertyChangedEventArgs e)
        {
            if (IsSelected)
            {
                VisualStateManager.GoToState(this, FocusedState, true);
                VisualStateManager.GoToState(this, SelectedState, true);
                Canvas.SetZIndex(this, 1000);
            }
            else
            {
                if (!_isMouseOver)
                {
                    VisualStateManager.GoToState(this, NormalState, true);
                }

                VisualStateManager.GoToState(this,  UnselectedState, true);
            }

            OnSelectionChanged(EventArgs.Empty);
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ColorPickerItem"/> class.
        /// </summary>
        public ColorPickerItem()
        {
            InitializeComponent();
        }

        #endregion

        #region Methods

        /// <summary>
        /// Called before the <see cref="E:System.Windows.UIElement.MouseEnter"/> event occurs.
        /// </summary>
        /// <param name="e">The data for the event.</param>
        protected override void OnMouseEnter(MouseEventArgs e)
        {
            Canvas.SetZIndex(this, 1000);

            VisualStateManager.GoToState(this, FocusedState, true);
            VisualStateManager.GoToState(this, MouseOverState, true);
            _isMouseOver = true;
        }

        /// <summary>
        /// Called before the <see cref="E:System.Windows.UIElement.MouseLeave"/> event occurs.
        /// </summary>
        /// <param name="e">The data for the event.</param>
        protected override void OnMouseLeave(MouseEventArgs e)
        {
            if (!IsSelected)
            {
                Canvas.SetZIndex(this, 0);
                VisualStateManager.GoToState(this, NormalState, true);
            }

            VisualStateManager.GoToState(this, MouseOutState, true);
            _isMouseOver = false;
        }

        /// <summary>
        /// Called before the <see cref="E:System.Windows.UIElement.MouseLeftButtonDown"/> event occurs.
        /// </summary>
        /// <param name="e">The data for the event.</param>
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            IsSelected = true;
        }

        #endregion
    }
}
